/**
 * Copyright (c) 2008, Mu Dynamics.
 *  All rights reserved.
 *  
 *   Redistribution and use in source and binary forms, with or without modification, 
 *   are permitted provided that the following conditions are met:
 *   
 *  - Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice, 
 *     this list of conditions and the following disclaimer in the documentation and/or 
 *     other materials provided with the distribution.
 *  - Neither the name of the "Mu Dynamics" nor the names of its contributors may be used 
 *     to endorse  or promote products derived from this software without specific prior 
 *     written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.mu.jacob.core.ant;

import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;

/**
 * Manages paths and class loader
 * @author Adam Smyczek
 *
 */
public class PathHelper {

	private Path path = null;
	private AntClassLoader loader = null;
	private Project project = null;
	
	/**
	 * Set project
	 * @param project
	 */
	public void setProject(Project project) {
		this.project = project;
		this.path = createPath();
	}
	
	/**
	 * @return returns the path
	 */
	public Path getPath() {
		return path;
	}
	
	/**
     * Set class path
     * @param path
     */
    public void setPath(Path path) {
		this.path = path;
    }

    /**
     * Add path to class path
     * @return class path
     */
    public Path createPath() {
    	path = new Path(project);
		return path;
    }
    
    /**
     * Set reference to class path
     * @param reference
     */
    public void setPathRef(Reference reference) {
    	Object refObject = reference.getReferencedObject(project);
    	if (refObject instanceof Path) {
    		if (path == null) {
    			path = (Path)refObject;
    		} else {
    			path.add((Path)refObject);
    		}
    	} else {
    		throw new BuildException("Referenced path is not a path type!");
    	}
    }
   
    /**
     * Set class loader with current class path
     * The loader is set only for changed path
     */
    protected void setThreadContextLoader() {
    	if (path != null) {
	    	loader = project.createClassLoader((path != null)? path : new Path(project));
	    	if ((Thread.currentThread().getContextClassLoader() != null) && 
	    			(Thread.currentThread().getContextClassLoader() instanceof AntClassLoader)) {
	    		loader.setParent(Thread.currentThread().getContextClassLoader());
	    	} else {
	    		loader.setParent(this.getClass().getClassLoader());
	    	}
			loader.setThreadContextLoader();
    	}
    }

    /**
     * Reset class loader
     */
    protected void resetThreadContextLoader() {
		if (loader != null) {
			loader.resetThreadContextLoader();
			loader.cleanup();
		}
    }
	
}
